package br.edu.unipampa.campeonato;

import br.edu.unipampa.clube.Clube;
import br.edu.unipampa.clube.Tecnico;
import java.util.ArrayList;
import java.util.Random;
/**
 * 
 * @author Antoni
 * @author Gean
 * 
 * Classe responsável por tratar os eventos de 
 * uma partida de futebol.
 */
public class PartidaDeFutebol {

    private Campeonato campeonato;// Campeonato conteendo todas os clubes
    private int scoreVisitante; // contador de gols do clube Visitante ou clube que Adversário
    private int scoreMandante; // contador de gols do clube Mandante ou clube que Dirige
    private Tecnico tecnico; // Tecnico 

    /**
     * Costrutor que recebe um tecnico e o campeonato
     * @param tecnico tecnico do clube que dirige 
     * @param campeonato campeonato ao qual serão disputadas as partidas
     */
    public PartidaDeFutebol(Tecnico tecnico, Campeonato campeonato) {
        this.tecnico = tecnico;
        this.campeonato = campeonato;
    }

    /**
     * Método que inicia a partida
     * e executa os turnos do
     * primeiro Tempo da partida
     */
    public void jogarPrimeiroTempo() {
        System.out.println("*********************** Inicia a Partida ***********************");
        System.out.println("<<<<<<<<<<<<<<<<<< " + tecnico.getClubeQueDirige().getNome() + " x "
                + tecnico.getClubeQueDirige().getClubeQueEnfrenta().getNome()
                + " >>>>>>>>>>>>>>>>>");
        System.out.println("+++++++++++++++++++++++ Jogo Válido pela " + campeonato.getNumeroDaRodada() + "ª Rodada!! +++++++++++++++++++++++");
        turnosClubeEscolhido();
    }
    
    /**
     * Método que retorna a partida
     * para executar os turnos
     * do segundo tempo e definir
     * quem venceu a partida, ou
     * se houve empate.
     */
    public void jogarSeguntoTempo() {
        System.out.println("*********************** Começa o Segundo Tempo ***********************");
        turnosClubeEscolhido();
        if (scoreMandante > scoreVisitante) {
            System.out.println("<<<<<<<<<<<<<<<<<< Parabéns! Seu time venceu o jogo.. >>>>>>>>>>>>>>>>>");
            tecnico.getClubeQueDirige().setVitoria(tecnico.getClubeQueDirige().getVitoria() + 1);
            tecnico.getClubeQueDirige().setPontos(tecnico.getClubeQueDirige().getPontos()+3);
            tecnico.getClubeQueDirige().getClubeQueEnfrenta().setDerrota(tecnico.getClubeQueDirige().getClubeQueEnfrenta().getDerrota() + 1);
        } else if (scoreVisitante > scoreMandante) {
            System.out.println("<<<<<<<<<<<<<<<<<< Seu time perdeu o jogo =/ >>>>>>>>>>>>>>>>>");
            tecnico.getClubeQueDirige().getClubeQueEnfrenta().setVitoria(tecnico.getClubeQueDirige().getClubeQueEnfrenta().getVitoria() + 1);
            tecnico.getClubeQueDirige().getClubeQueEnfrenta().setPontos(tecnico.getClubeQueDirige().getClubeQueEnfrenta().getPontos()+3);
            tecnico.getClubeQueDirige().setDerrota(tecnico.getClubeQueDirige().getDerrota() + 1);
        } else {
            System.out.println("<<<<<<<<<<<<<<<<<< Jogo empatado >>>>>>>>>>>>>>>>>");
            tecnico.getClubeQueDirige().getClubeQueEnfrenta().setEmpate(tecnico.getClubeQueDirige().getClubeQueEnfrenta().getEmpate() + 1);
            tecnico.getClubeQueDirige().getClubeQueEnfrenta().setPontos(tecnico.getClubeQueDirige().getClubeQueEnfrenta().getPontos()+1);
            tecnico.getClubeQueDirige().setEmpate(tecnico.getClubeQueDirige().getEmpate() + 1);
            tecnico.getClubeQueDirige().setPontos(tecnico.getClubeQueDirige().getPontos()+1);
        }
        System.out.println("\n*********************** Fim de Jogo ***********************");
        scoreMandante = 0;
        scoreVisitante = 0;
    }

    /**
     * Método responsável por fazer as ações
     * dos clubes durante a partida. A partida
     * foi separada em turnos, onde um clube
     * ataca e depois é atacado. Sendo que foram
     * definidos quatro turnos por tempo.
     * Dois para o Mandante e dois para o Visitante
     */
    private void turnosClubeEscolhido() {
        turnoAtaque(tecnico.getClubeQueDirige(), tecnico.getClubeQueDirige().getClubeQueEnfrenta());
        System.out.println("");
        turnoDefesa(tecnico.getClubeQueDirige(), tecnico.getClubeQueDirige().getClubeQueEnfrenta());
        System.out.println("");
        turnoAtaque(tecnico.getClubeQueDirige(), tecnico.getClubeQueDirige().getClubeQueEnfrenta());
        System.out.println("");
        turnoDefesa(tecnico.getClubeQueDirige(), tecnico.getClubeQueDirige().getClubeQueEnfrenta());
    }

    /**
     * Método responsável por separar quais clubes ja estão
     * envolvidos na partida com o usuário, para que se
     * possa pegar esse clubes e fazer as devidas simulaçoes.
     * @return clubes a serem feitas simulaçoes.
     */
    public ArrayList<Clube> clubesSimulacao(){
        ArrayList<Clube> clubesParaSimulacao = new ArrayList<Clube>();
        for (int i = 0; i < campeonato.getClubes().size(); i++) {
            if((campeonato.getClubes().get(i).equals(tecnico.getClubeQueDirige()))){
                
            }else if(campeonato.getClubes().get(i).equals(tecnico.getClubeQueDirige().getClubeQueEnfrenta())){
                
            }else{
                clubesParaSimulacao.add(campeonato.getClubes().get(i));
            }           
        }
        return clubesParaSimulacao;
    }
    /**
     * Método que simula os turnos dos Clubes
     * que serão feitas simulações de resultados
     * @param mandante clube 1
     * @param visitante clube 2
     */
    public void simulaOutrosJogos(Clube mandante, Clube visitante) {
        for (int i = 0; i < 4; i++) {
            //Turno de ataque do Visitante
            int defesaMandante = defineAtaqueDefesa(calculaDefesa(mandante));
            int ataqueVisitante = defineAtaqueDefesa(calculaAtaque(visitante));
            if (ataqueVisitante > defesaMandante) {
                scoreVisitante++;
            }
            // Turno de ataque Mandante
            int ataqueMandante = defineAtaqueDefesa(calculaAtaque(mandante));
            int defesaVisitante = defineAtaqueDefesa(calculaDefesa(visitante));
            if (ataqueMandante > defesaVisitante) {
                scoreMandante++; // Gol Mandante
            }
        }
        if (scoreMandante > scoreVisitante) {
            System.out.println("Vitoria do "+mandante.getNome());
            mandante.setVitoria(mandante.getVitoria() + 1);
            mandante.setPontos(mandante.getPontos()+3);
            visitante.setDerrota(visitante.getDerrota() + 1);
        }
        if (scoreVisitante > scoreMandante) {
            System.out.println("Vitoria do "+visitante.getNome());
            visitante.setVitoria(visitante.getVitoria() + 1);
            visitante.setPontos(visitante.getPontos()+3);
            mandante.setDerrota(mandante.getDerrota() + 1);
        }
        if(scoreMandante == scoreVisitante){
            System.out.println("Empate");     
            visitante.setEmpate(visitante.getEmpate() + 1);
            visitante.setPontos(visitante.getPontos()+1);
            mandante.setEmpate(mandante.getEmpate() + 1);
            mandante.setPontos(mandante.getPontos()+1);
            System.out.println("*** Num empates do "+visitante.getNome()+" "+visitante.getEmpate());
            System.out.println("*** Num empates do "+mandante.getNome()+" "+mandante.getEmpate());
        }
        System.out.println("<<<<<<<< "+mandante.getNome()+" "+scoreMandante+" x "+scoreVisitante+ " "+visitante.getNome()+" >>>>>>>>>>>");
        scoreMandante = 0;
        scoreVisitante = 0;
    }
    
    /**
     * Método responsável pelo turno de ataque dos Clubes,
     * onde compara os atributos de ataque e defesa dos mesmos.
     * Caso o ataque do mandante seja maior que a defesa do visitante
     * é gol do clube mandante, caso contrario o ataque é interceptado
     * @param mandante clube que dirige
     * @param visitante clube adversário
     */
    private void turnoAtaque(Clube mandante, Clube visitante) {
        int ataqueMandante = defineAtaqueDefesa(calculaAtaque(mandante));
        int defesaVisitante = defineAtaqueDefesa(calculaDefesa(visitante));
        System.out.println("-------- Seu Time está no ataque... --------");
        System.out.println("Ataque: " + ataqueMandante + " Defesa " + defesaVisitante);
        if (ataqueMandante > defesaVisitante) {
            System.out.println("Feitooo!!! Gooooool.");
            scoreMandante++; // Gol Mandante
        } else {
            System.out.println("Ataque Interceptado...");
        }
        System.out.println("============================= PLACAR " + scoreMandante + " x " + scoreVisitante + " =============================");
    }
    
    /**
     * Método responsável pelo turno de defesa dos Clubes,
     * onde compara os atributos de ataque e defesa dos mesmos.
     * Caso a defesa do mandante seja maior ou igual ao ataque do visitante
     * o ataque é bloqueado, caso contrario marcado gol para o time visitante
     * @param mandante clube que dirige
     * @param visitante clube adversário
     */
    private void turnoDefesa(Clube mandante, Clube visitante) {
        int defesaMandante = defineAtaqueDefesa(calculaDefesa(mandante));
        int ataqueVisitante = defineAtaqueDefesa(calculaAtaque(visitante));
        System.out.println("------------- Time visitante no ataque... ---------------- ");
        System.out.println("Ataque: " + ataqueVisitante + " Defesa " + defesaMandante);
        if (ataqueVisitante > defesaMandante) {
            System.out.println("Goooool do time adversário");
            scoreVisitante++;// Gol Visitante
        } else {
            System.out.println("Seu time bloqueou o ataque do adversário...");
        }
        System.out.println("============================= PLACAR " + scoreMandante + " x " + scoreVisitante + " =============================");
    }
    
    /**
     * Método que calcula a média do ataque de um Clube
     * Soma-se todas os ataques de cada jogador e 
     * divide-se pelo quantidade de jogadores do clube
     * o numero resultante é a média de atauqe desse clube
     * @param x Clube que deseja calcular a media de ataque.
     * @return media de ataque
     */
    private int calculaAtaque(Clube x) {
        double ataqueTotal = 0;
        for (int i = 0; i < x.getListaDeJogadoresTitularesDaPartida().size(); i++) {
            ataqueTotal = ataqueTotal + x.getListaDeJogadoresTitularesDaPartida().get(i).getAtaque();
        }
        ataqueTotal = ataqueTotal / 11;
        int result = (int) Math.round(ataqueTotal);
        return result;
    }

      /**
     * Método que calcula a média da defesa de um Clube
     * Soma-se todas as defesas de cada jogador e 
     * divide-se pelo quantidade de jogadores do clube
     * o numero resultante é a média de defesa desse clube
     * @param x Clube que deseja calcular a media de ataque.
     * @return media de defesa
     */
    private int calculaDefesa(Clube y) {
        double defesaTotal = 0;
        for (int i = 0; i < y.getListaDeJogadoresTitularesDaPartida().size(); i++) {
            defesaTotal = defesaTotal + y.getListaDeJogadoresTitularesDaPartida().get(i).getDefesa();
        }
        defesaTotal = defesaTotal / 11;
        int result = (int) Math.round(defesaTotal);
        return result;
    }
    /**
     * Método responsavel por sortear o valor do ataque
     * ou da defesa de um clube, sorteando de 0 até o valor da media do clube
     * @param ataqueDefesaCalculado media de ataque ou defesa de um clube
     * @return o valor sorteado.
     */
    private int defineAtaqueDefesa(int ataqueDefesaCalculado) {
        Random baralho = new Random();
        int saida = baralho.nextInt(ataqueDefesaCalculado);
        return saida;
    }

    public Campeonato getCampeonato() {
        return campeonato;
    }

    public void setCampeonato(Campeonato campeonato) {
        this.campeonato = campeonato;
    }

}
